import * as cc from "cc";
import { AService, ServiceType } from "./AService";
import { WChannel } from "./WChannel";
import { Dictionary } from "../../../Support/Share/Lib/Dictionary";
import { WebSocketExtentions } from "../../../Support/Share/WebSocket/WebSocketExtentions";

declare const CC_JSB;

export class WService extends AService {

    private readonly channels = new Dictionary<number, WChannel>();

    constructor(serviceType: ServiceType = ServiceType.Outer) {
        super();

        this.ServiceType = serviceType;
    }

    public Update() {
    }

    public Remove(id: number, error: number = 0) {
        let channel = this.channels.TryGetValue(id);
        if (!channel) {
            return;
        }
        channel.Error = error;
        this.channels.Remove(id);
        channel.Dispose();
    }

    public IsDispose() {
    }

    public async Create(id: number, address: string) {
        let webSocket: WebSocket = null;
        if (CC_JSB && cc.sys.OS.ANDROID === cc.sys.os) {
            let protocols = WebSocketExtentions.GetProtocols();
            let url = WebSocketExtentions.GetCAUrl();
            // @ts-ignore
            webSocket = new WebSocket(address, protocols, url);
        } else {
            webSocket = new WebSocket(address);
        }
        let channel = new WChannel(id, webSocket, this);
        await channel.initWebSocket();
        this.channels.Add(channel.Id, channel);
        return channel;
    }

    public Send(channelId: number, actorId: number, message: any) {
        let channel = this.channels.TryGetValue(channelId);
        if (channel == null) {
            return;
        }
        let memoryStream = this.GetMemoryStream(message);
        channel.Send(actorId, memoryStream.buffer);
    }

    public Dispose() {
        super.Dispose();
    }

}